package com.ershi.spring.aop.code;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

/**
 * @author 二十
 * @since 2021/10/28 2:32 下午
 */
public class CodeMain {

	public static void main(String[] args) {

		//默认代理所有方法
		proxyAllMethods();
		//定制代理
		//proxyMethod();
	}

	/**
	 * 默认情况。代理所有方法
	 */
	private static void proxyAllMethods(){
		//1.创建被代理对象
		Tiger tiger = new Tiger();
		//2.创建spring代理工厂对象 ProxyFactory
		//proxyFactory 是 config + factory 的存在  持有 aop 操作 的 所有的生产资料
		ProxyFactory proxyFactory = new ProxyFactory(tiger);
		//3. 添加拦截器
		proxyFactory.addAdvice(new MethodInterceptor01());
		proxyFactory.addAdvice(new MethodInterceptor02());
		//4.获取代理对象，分析如何获取的代理对象？
		Animals proxy = (Animals) proxyFactory.getProxy();
		proxy.eat("人");
		System.out.println("===================================");
		proxy.run();
	}

	/**
	 * 代理指定的方法
	 */
	private static void proxyMethod(){

		//1.创建被代理对象
		Tiger tiger = new Tiger();
		//2.创建spring代理工厂对象 ProxyFactory
		//proxyFactory 是 config + factory 的存在  持有 aop 操作 的 所有的生产资料
		ProxyFactory proxyFactory = new ProxyFactory(tiger);
		//3.添加方法拦截
		MyPointCut pointCut = new MyPointCut();
		proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointCut,new MethodInterceptor01()));
		proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointCut,new MethodInterceptor02()));
		//4.获取代理对象 分析如何获得代理对象
		Animals proxy = (Animals) proxyFactory.getProxy();

		proxy.eat("人肉");
		System.out.println("===================================");
		proxy.run();
	}

	/**
	 * 方法拦截器
	 */
	private static class MethodInterceptor01 implements MethodInterceptor {

		@Nullable
		@Override
		public Object invoke(@NonNull MethodInvocation invocation) throws Throwable{
			System.out.println("method interceptor begin!----1");
			Object result = invocation.proceed();
			System.out.println("method interceptor end!---4");
			return result;
		}
	}
	private static class MethodInterceptor02 implements MethodInterceptor {

		@Nullable
		@Override
		public Object invoke(@NonNull MethodInvocation invocation) throws Throwable{
			System.out.println("method interceptor begin!----2");
			Object result = invocation.proceed();
			System.out.println("method interceptor end!----3");
			return result;
		}
	}
}
